package org.openclinic.repository.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.openclinic.domain.Appointment;
import org.openclinic.repository.ReportsRepository;
import org.openclinic.to.ReportParametersTO;
import org.springframework.stereotype.Repository;

@Repository
public class ReportsRepositoryImpl implements ReportsRepository {

	@PersistenceContext
	private EntityManager em;

	@Override
	@SuppressWarnings("unchecked")
	public List<Appointment> getReportResults(ReportParametersTO parameters) {
		boolean hasWhere = false;
		int paramCount = 1;
		String sqlString = "SELECT * FROM appointment";

		if (parameters.getSpecialtyId() != null) {
			sqlString += getConcatClause(hasWhere) + " specialty_id = ?"; 
			hasWhere = true;
		}

		if (parameters.getProfessionalId() != null) {
			sqlString += getConcatClause(hasWhere) + " professional_id = ?"; 
			hasWhere = true;
		}

		if (parameters.getCustomerId() != null) {
			sqlString += getConcatClause(hasWhere) + " customer_id = ?"; 
			hasWhere = true;
		}
		
		if (parameters.getCanceled() != null) {
			sqlString += getConcatClause(hasWhere) + " canceled = ?"; 
			hasWhere = true;
		}

		if (parameters.getStartDate() != null) {
			sqlString += getConcatClause(hasWhere) + " date_trunc('day', start_date) >= ?"; 
			hasWhere = true;
		}

		if (parameters.getEndDate() != null) {
			sqlString += getConcatClause(hasWhere) + " date_trunc('day', end_date) <= ?";
			hasWhere = true;
		}
		
		sqlString += " ORDER BY start_date";
		
		Query query = em.createNativeQuery(sqlString, Appointment.class);
		
		if (parameters.getSpecialtyId() != null)
			query.setParameter(paramCount++, parameters.getSpecialtyId());
		
		if (parameters.getProfessionalId() != null)
			query.setParameter(paramCount++, parameters.getProfessionalId());
		
		if (parameters.getCustomerId() != null)
			query.setParameter(paramCount++, parameters.getCustomerId());
		
		if (parameters.getCanceled() != null)
			query.setParameter(paramCount++, parameters.getCanceled());
		
		if (parameters.getStartDate() != null)
			query.setParameter(paramCount++, parameters.getStartDate());

		if (parameters.getEndDate() != null)
			query.setParameter(paramCount++, parameters.getEndDate());
		
		return query.getResultList();
	}
	
	private String getConcatClause(boolean hasWhere) {
		return !hasWhere ? " WHERE " : " AND ";
	}
}
